/*
	消息管理模块的测试
*/

#include "../../src/server/message.hpp"
#include "gtest/gtest.h"

mq::MessageManager::MessageManagerPtr message_manager_ptr;
class MessageTest : public testing::Environment
{
public:
	virtual void SetUp() override
	{
		std::string dir = "./data";
		message_manager_ptr = std::make_shared<mq::MessageManager>(dir);
	}

	virtual void TearDown() override
	{
		message_manager_ptr->clear();
	}
};

// 插入测试
TEST(message_test, insert_msg)
{
	mq::BasicProperties properties;
	properties.set_id(mq::UUIDHelper::uuid());
	properties.set_delivery_mode(mq::DeliveryMode::DURABLE);
	properties.set_routing_key("news.music.pop");
    message_manager_ptr->insertMsg("queue_1", &properties, "hello world queue_1::message_1", true);
	message_manager_ptr->insertMsg("queue_1", nullptr, "hello world queue_1::message_2", true);
	message_manager_ptr->insertMsg("queue_2", nullptr,"hello world queue_2::message_1", true);
	message_manager_ptr->insertMsg("queue_2", nullptr, "hello world queue_2::message_2", false);
	message_manager_ptr->insertMsg("queue_3", nullptr, "hello world queue_3::message_1", true);
	message_manager_ptr->insertMsg("queue_3", nullptr, "hello world queue_3::message_2", false);
	// queue_1
	ASSERT_EQ(message_manager_ptr->getPushCnt("queue_1"), 2);
	ASSERT_EQ(message_manager_ptr->getTotalCnt("queue_1"), 2);
	ASSERT_EQ(message_manager_ptr->getValidCnt("queue_1"), 2);
	ASSERT_EQ(message_manager_ptr->getWaittingAckCnt("queue_1"), 0);
	// queue_2
	ASSERT_EQ(message_manager_ptr->getPushCnt("queue_2"), 2);
	ASSERT_EQ(message_manager_ptr->getTotalCnt("queue_2"), 1);
	ASSERT_EQ(message_manager_ptr->getValidCnt("queue_2"), 1);
	ASSERT_EQ(message_manager_ptr->getWaittingAckCnt("queue_2"), 0);
	// queue_3
	ASSERT_EQ(message_manager_ptr->getPushCnt("queue_3"), 2);
	ASSERT_EQ(message_manager_ptr->getTotalCnt("queue_3"), 1);
	ASSERT_EQ(message_manager_ptr->getValidCnt("queue_3"), 1);
	ASSERT_EQ(message_manager_ptr->getWaittingAckCnt("queue_3"), 0);
}

// // 恢复测试
// TEST(message_test, recover)
// {
// 	message_manager_ptr->initQueueMessages({"queue_1", "queue_2", "queue_3"});
// 	// queue_1
// 	ASSERT_EQ(message_manager_ptr->getPushCnt("queue_1"), 2);
// 	ASSERT_EQ(message_manager_ptr->getTotalCnt("queue_1"), 2);
// 	ASSERT_EQ(message_manager_ptr->getValidCnt("queue_1"), 2);
// 	ASSERT_EQ(message_manager_ptr->getWaittingAckCnt("queue_1"), 0);
// 	// queue_2
// 	ASSERT_EQ(message_manager_ptr->getPushCnt("queue_2"), 1);
// 	ASSERT_EQ(message_manager_ptr->getTotalCnt("queue_2"), 1);
// 	ASSERT_EQ(message_manager_ptr->getValidCnt("queue_2"), 1);
// 	ASSERT_EQ(message_manager_ptr->getWaittingAckCnt("queue_2"), 0);
// 	// queue_3
// 	ASSERT_EQ(message_manager_ptr->getPushCnt("queue_3"), 1);
// 	ASSERT_EQ(message_manager_ptr->getTotalCnt("queue_3"), 1);
// 	ASSERT_EQ(message_manager_ptr->getValidCnt("queue_3"), 1);
// 	ASSERT_EQ(message_manager_ptr->getWaittingAckCnt("queue_3"), 0);
// }

// 获取队头元素以及应答测试
TEST(message_test, pop_front_test_and_ack_test)
{
	// queue_1
	// 出队头
	mq::MessagePtr msg_ptr = message_manager_ptr->popFront("queue_1");
	ASSERT_EQ(msg_ptr->payload().properties().routing_key(), "news.music.pop");
	ASSERT_EQ(msg_ptr->payload().body(), "hello world queue_1::message_1");
	ASSERT_EQ(message_manager_ptr->getPushCnt("queue_1"), 1);
	ASSERT_EQ(message_manager_ptr->getTotalCnt("queue_1"), 2);
	ASSERT_EQ(message_manager_ptr->getValidCnt("queue_1"), 2);
	ASSERT_EQ(message_manager_ptr->getWaittingAckCnt("queue_1"), 1);
	// 应答
	message_manager_ptr->ackMsg("queue_1", msg_ptr->payload().properties().id());
	// 注意这里还是2，因为应答之后虽然会将内存中持久化映射表和持久化文件中对应消息删除
	// 但是持久化文件是伪删除，total描述的是持久化文件中所有消息，包括伪删除消息
	ASSERT_EQ(message_manager_ptr->getPushCnt("queue_1"), 1);
	ASSERT_EQ(message_manager_ptr->getTotalCnt("queue_1"), 2);
	ASSERT_EQ(message_manager_ptr->getValidCnt("queue_1"), 1);
	ASSERT_EQ(message_manager_ptr->getWaittingAckCnt("queue_1"), 0);

	// queue_2
	// 出队头
	msg_ptr = message_manager_ptr->popFront("queue_2");
	ASSERT_EQ(msg_ptr->payload().body() , "hello world queue_2::message_1");
	ASSERT_EQ(message_manager_ptr->getPushCnt("queue_2"), 1);
	ASSERT_EQ(message_manager_ptr->getTotalCnt("queue_2"), 1);
	ASSERT_EQ(message_manager_ptr->getValidCnt("queue_2"), 1);
	ASSERT_EQ(message_manager_ptr->getWaittingAckCnt("queue_2"), 1);
	// 应答
	message_manager_ptr->ackMsg("queue_2", msg_ptr->payload().properties().id());
	ASSERT_EQ(message_manager_ptr->getPushCnt("queue_2"), 1);
	ASSERT_EQ(message_manager_ptr->getTotalCnt("queue_2"), 1);
	ASSERT_EQ(message_manager_ptr->getValidCnt("queue_2"), 0);
	ASSERT_EQ(message_manager_ptr->getWaittingAckCnt("queue_2"), 0);

	// queue_3
	// 出队头
	msg_ptr = message_manager_ptr->popFront("queue_3");
	ASSERT_EQ(msg_ptr->payload().body() , "hello world queue_3::message_1");
	ASSERT_EQ(message_manager_ptr->getPushCnt("queue_3"), 1);
	ASSERT_EQ(message_manager_ptr->getTotalCnt("queue_3"), 1);
	ASSERT_EQ(message_manager_ptr->getValidCnt("queue_3"), 1);
	ASSERT_EQ(message_manager_ptr->getWaittingAckCnt("queue_3"), 1);
	// 应答
	message_manager_ptr->ackMsg("queue_3", msg_ptr->payload().properties().id());
	ASSERT_EQ(message_manager_ptr->getPushCnt("queue_3"), 1);
	ASSERT_EQ(message_manager_ptr->getTotalCnt("queue_3"), 1);
	ASSERT_EQ(message_manager_ptr->getValidCnt("queue_3"), 0);
	ASSERT_EQ(message_manager_ptr->getWaittingAckCnt("queue_3"), 0);
}

// 销毁队列测试
TEST(message_test, destroy_test)
{
	// queue_2
	message_manager_ptr->destroyQueueMessage("queue_2");
	ASSERT_EQ(message_manager_ptr->queueMsgSize(), 2);

	// queue_3
	message_manager_ptr->destroyQueueMessage("queue_3");
	ASSERT_EQ(message_manager_ptr->queueMsgSize(), 1);
}

int main(int argc, char *argv[])
{
    testing::InitGoogleTest(&argc, argv);
    testing::AddGlobalTestEnvironment(new MessageTest);
    return RUN_ALL_TESTS();
}